COPY FROM

COPY FROM

am 08.02.2006 11:03:55 von Bart Degryse

This is a MIME message. If you are reading this text, you may want to
consider changing to a mail reader or gateway that understands how to
properly handle MIME multipart messages.

--=__Part1B39BC1B.0__=
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: quoted-printable


Dear,
I need to do a bulk upload (2,600,000 records) of data into a PostgreSQL =
(v8.0.3) table. I'm trying to achieve this from Visual Basic with ADO and =
psqlODBC (v8.1.2) but I can't get it working. Currently my code looks like =
this. Dim conn As New ADODB.Connection Dim query As String 'DSN =
less connection query =3D "DRIVER=3D{PostgreSQL Unicode};SERVER=3D10.100=
..1.24;PORT=3D2345;DATABASE=3Dbigdb;BoolsAsChar=3D0;TrueIsMi nus1=3D1;Debug=
=3D0;CommLog=3D0" conn.CursorLocation =3D adUseClient conn.Open =
query, "bad", "xxxxxxxx" query =3D "COPY dunn_main (duns, company, =
company_short, zip, phone, employee_number, legal_id, sic_id, source_id) " =
& _ "FROM STDIN WITH NULL AS 'NULL' DELIMITER AS ','" =
conn.Execute query, , adCmdText + adExecuteNoRecords + adAsyncExecute
In the driver logging I can see that it's waiting for the data now, but I =
can't really figure out how to deliver it. Since the source data (as a =
text file with fixed length fields) is only available on client side and =
needs some processing before being ready to import I'm using something =
like this to prepare the data:=20
Private Type Dunn_Record CO_NAME As String * 90 PCODE As =
String * 8 DUNS As String * 9 EMPS_COMP As String * 9 =
LE As String * 2 L As String * 1 TEL_NBR As String * 14 =
US72 As String * 4 crlf As String * 2 End Type Dim record =
As Dunn_Record Dim filehandle As Integer Dim filename As String =
Dim numLines as long Dim line As Long filehandle =3D FreeFile =
filename =3D "E:\source.txt" Open filename For Random Access Read Lock =
Read Write As #filehandle Len =3D Len(record) numLines =3D LOF(1) / =
Len(record) For line =3D 2 to numLines Get #filehandle, line, =
record With record query =3D query & CLng(.DUNS) & "," =
query =3D query & "'" & Replace(Trim(.CO_NAME), "'", "''") & "'," =
query =3D query & "'" & ascii_easy(.CO_NAME) & "'," =
query =3D query & "'" & Trim(.PCODE) & "'," query =3D query & =
phone(.TEL_NBR) & "," If Len(Trim(.EMPS_COMP)) Then query =3D =
query & CLng(.EMPS_COMP) Else query =3D query & "NULL" query =
=3D query & "," If Len(Trim(.LE)) Then query =3D query & =
CLng(.LE) Else query =3D query & "NULL" query =3D query & "," =
query =3D query & CLng(.US72) & "," query =3D query & =
rs!source_id End With 'DELIVER THE DATA IN query TO THE =
DRIVER Next lineI have tried several methods to deliver the prepared =
data to the driver but without any succes.=20
Writing to STDOUT
Private Declare Function GetStdHandle Lib "Kernel32" (ByVal nStdHandle =
As Long) As Long Private Declare Function WriteFile Lib "Kernel32" =
(ByVal hFile As Long, ByVal lpBuffer As String, ByVal nNumberOfBytesToWrite=
As Long, lpNumberOfBytesWritten As Long, lpOverlapped As Any) As Long =
Private Const STD_OUTPUT_HANDLE =3D -11& Dim stdhandle As Long Dim =
llResult As Long stdhandle =3D GetStdHandle(STD_OUTPUT_HANDLE) =
WriteFile stdhandle, query, Len(query), llResult, ByVal 0&Writing to a =
socket
Dim socket As New Winsock With socket .Protocol =3D =
sckUDPProtocol .RemoteHost =3D "10.100.1.24" .RemotePort =3D =
2345 .Connect End With socket.SendData queryExecuting it
conn.Execute queryWriting to some stream
Dim str As New Stream With str .Mode =3D adModeWrite =
..Open End With str.WriteText query
So basically my question is : how do I deliver the prepared data to the =
driver? Any help (tips, working code, example, ...) would be appreciated.=
=20
Best regards

--=__Part1B39BC1B.0__=
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Description: HTML


>


Dear,
I need to do a bulk upload (2,600,000 records) of data into a =
PostgreSQL (v8.0.3) table. I'm trying to achieve this from Visual Basic =
with ADO and psqlODBC (v8.1.2) but I can't get it working. Currently my =
code looks like this.

    Dim conn As New ADODB.Connection
Dim query As String

'DSN less connection
query =3D "DRIVER=3D{PostgreSQL Unicode};SERVER=3D10.100.1.24;PORT=3D23=
45;DATABASE=3Dbigdb;BoolsAsChar=3D0;TrueIsMinus1=3D1;Debug=3 D0;CommLog=3D0"=

conn.CursorLocation =3D adUseClient
conn.Open query, "bad", "xxxxxxxx"

query =3D "COPY dunn_main (duns, company, company_short, zip, phone, =
employee_number, legal_id, sic_id, source_id) " & _
"FROM STDIN WITH NULL AS 'NULL' DELIMITER AS ','"
conn.Execute query, , adCmdText + adExecuteNoRecords + adAsyncExecute

In the driver logging I can see that it's waiting for the data now, but =
I can't really figure out how to deliver it. Since the source data (as a =
text file with fixed length fields) is only available on client side and =
needs some processing before being ready to import I'm using something =
like this to prepare the data:=20

    Private Type Dunn_Record
CO_NAME As String * 90
PCODE As String * 8
DUNS As String * 9
EMPS_COMP As String * 9
LE As String * 2
L As String * 1
TEL_NBR As String * 14
US72 As String * 4
crlf As String * 2
End Type
Dim record As Dunn_Record
Dim filehandle As Integer
Dim filename As String
Dim numLines as long
Dim line As Long
filehandle =3D FreeFile
filename =3D "E:\source.txt"
Open filename For Random Access Read Lock Read Write As #filehandle =
Len =3D Len(record)
numLines =3D LOF(1) / Len(record)
For line =3D 2 to numLines
Get #filehandle, line, record
With record
query =3D query & CLng(.DUNS) & ","
query =3D query & "'" & Replace(Trim(.CO_NAME), "'", =
"''") & "',"
query =3D query & "'" & ascii_easy(.CO_NAME) & =
"',"
query =3D query & "'" & Trim(.PCODE) & "',"
query =3D query & phone(.TEL_NBR) & ","
If Len(Trim(.EMPS_COMP)) Then query =3D query & CLng(.EMPS_=
COMP) Else query =3D query & "NULL"
query =3D query & ","
If Len(Trim(.LE)) Then query =3D query & CLng(.LE) Else =
query =3D query & "NULL"
query =3D query & ","
query =3D query & CLng(.US72) & ","
query =3D query & rs!source_id
End With
'DELIVER THE DATA IN query TO THE DRIVER
Next line
I have tried several methods to deliver the prepared data to the =
driver but without any succes.=20



So basically my question is : how do I deliver the prepared data to the =
driver? Any help (tips, working code, example, ...) would be appreciated. p>=20

Best regards



--=__Part1B39BC1B.0__=--

Re: COPY FROM

am 08.02.2006 16:18:00 von Bart Degryse

This is a MIME message. If you are reading this text, you may want to
consider changing to a mail reader or gateway that understands how to
properly handle MIME multipart messages.

--=__Part7250D6B8.1__=
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: quoted-printable

Hi Miguel,
I had the same idea, but I don't have (and will not get) access to the =
server. So I can't copy or ftp the file to the server. That is why I was =
trying to use the STDIN way.
So your idea doesn't help me, but thanks anyway for sharing it.
Best regards
Bart

>>> "Miguel Juan" 2006-02-08 14:57 >>>

Hello Bart,
=20
I have done it using a temp File. First you must copy the file with the =
data to a shared folder in the database server. Then you have to execute =
the comand "COPY FROM file xxxxxx", where "file" is referencing the =
path+filename as it is seen by the server.
=20
I hope this helps you,
=20
Regards
=20
Miguel Juan
=20
=20
----- Original Message -----=20
From: Bart Degryse=20
To: pgsql-odbc@postgresql.org=20
Cc: Bart Degryse=20
Sent: Wednesday, February 08, 2006 11:03 AM
Subject: [ODBC] COPY FROM



Dear,
I need to do a bulk upload (2,600,000 records) of data into a PostgreSQL =
(v8.0.3) table. I'm trying to achieve this from Visual Basic with ADO and =
psqlODBC (v8.1.2) but I can't get it working. Currently my code looks like =
this. Dim conn As New ADODB.Connection Dim query As String 'DSN =
less connection query =3D "DRIVER=3D{PostgreSQL Unicode};SERVER=3D10.100=
..1.24;PORT=3D2345;DATABASE=3Dbigdb;BoolsAsChar=3D0;TrueIsMi nus1=3D1;Debug=
=3D0;CommLog=3D0" conn.CursorLocation =3D adUseClient conn.Open =
query, "bad", "xxxxxxxx" query =3D "COPY dunn_main (duns, company, =
company_short, zip, phone, employee_number, legal_id, sic_id, source_id) " =
& _ "FROM STDIN WITH NULL AS 'NULL' DELIMITER AS ','" =
conn.Execute query, , adCmdText + adExecuteNoRecords + adAsyncExecute
In the driver logging I can see that it's waiting for the data now, but I =
can't really figure out how to deliver it. Since the source data (as a =
text file with fixed length fields) is only available on client side and =
needs some processing before being ready to import I'm using something =
like this to prepare the data:=20
Private Type Dunn_Record CO_NAME As String * 90 PCODE As =
String * 8 DUNS As String * 9 EMPS_COMP As String * 9 =
LE As String * 2 L As String * 1 TEL_NBR As String * 14 =
US72 As String * 4 crlf As String * 2 End Type Dim record =
As Dunn_Record Dim filehandle As Integer Dim filename As String =
Dim numLines as long Dim line As Long filehandle =3D FreeFile =
filename =3D "E:\source.txt" Open filename For Random Access Read Lock =
Read Write As #filehandle Len =3D Len(record) numLines =3D LOF(1) / =
Len(record) For line =3D 2 to numLines Get #filehandle, line, =
record With record query =3D query & CLng(.DUNS) & "," =
query =3D query & "'" & Replace(Trim(.CO_NAME), "'", "''") & "'," =
query =3D query & "'" & ascii_easy(.CO_NAME) & "'," =
query =3D query & "'" & Trim(.PCODE) & "'," query =3D query & =
phone(.TEL_NBR) & "," If Len(Trim(.EMPS_COMP)) Then query =3D =
query & CLng(.EMPS_COMP) Else query =3D query & "NULL" query =
=3D query & "," If Len(Trim(.LE)) Then query =3D query & =
CLng(.LE) Else query =3D query & "NULL" query =3D query & "," =
query =3D query & CLng(.US72) & "," query =3D query & =
rs!source_id End With 'DELIVER THE DATA IN query TO THE =
DRIVER Next lineI have tried several methods to deliver the prepared =
data to the driver but without any succes.=20
Writing to STDOUT
Private Declare Function GetStdHandle Lib "Kernel32" (ByVal nStdHandle =
As Long) As Long Private Declare Function WriteFile Lib "Kernel32" =
(ByVal hFile As Long, ByVal lpBuffer As String, ByVal nNumberOfBytesToWrite=
As Long, lpNumberOfBytesWritten As Long, lpOverlapped As Any) As Long =
Private Const STD_OUTPUT_HANDLE =3D -11& Dim stdhandle As Long Dim =
llResult As Long stdhandle =3D GetStdHandle(STD_OUTPUT_HANDLE) =
WriteFile stdhandle, query, Len(query), llResult, ByVal 0&Writing to a =
socket
Dim socket As New Winsock With socket .Protocol =3D =
sckUDPProtocol .RemoteHost =3D "10.100.1.24" .RemotePort =3D =
2345 .Connect End With socket.SendData queryExecuting it
conn.Execute queryWriting to some stream
Dim str As New Stream With str .Mode =3D adModeWrite =
..Open End With str.WriteText query
So basically my question is : how do I deliver the prepared data to the =
driver? Any help (tips, working code, example, ...) would be appreciated.=
=20
Best regards


--=__Part7250D6B8.1__=
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Description: HTML


>



ffff>

Hi Miguel,

I had the same idea, but I don't have (and will not get) access =
to the server. So I can't copy or ftp the file to the server. That is why =
I was trying to use the STDIN way.

So your idea doesn't help me, but thanks anyway for sharing it.

Best regards

Bart

>>> "Miguel Juan" <mjuan@cibal.es> =
2006-02-08 14:57 >>>


Hello Bart,

 

I have done it using a temp File. First =
you must copy the file with the data to a shared folder in the database =
server. Then you have to execute the comand "COPY FROM file xxxxxx", =
where "file" is referencing the path+filename as it is seen by the =
server.

 

I hope this helps you,

 

Regards

 

Miguel Juan

 

 

MARGIN-LEFT: 5px; BORDER-LEFT: #000000 2px solid; MARGIN-RIGHT: 0px">
----- Original Message -----

=
From:
indicator.be">Bart Degryse

To: ..org href=3D"mailto:pgsql-odbc@postgresql.org">pgsql-odbc@postgre sql.org >

Cc: r.be href=3D"mailto:Bart.Degryse@indicator.be">Bart Degryse

Sent: Wednesday, February 08, 2006 =
11:03 AM

Subject: [ODBC] COPY FROM



Dear,
I need to do a bulk upload (2,600,000 records) of data into a =
PostgreSQL (v8.0.3) table. I'm trying to achieve this from Visual Basic =
with ADO and psqlODBC (v8.1.2) but I can't get it working. Currently my =
code looks like this.

    Dim conn As New ADODB.Connection
Dim query As String

'DSN less connection
query =3D "DRIVER=3D{PostgreSQL Unicode};SERVER=3D10.100.1.24;PORT=3D23=
45;DATABASE=3Dbigdb;BoolsAsChar=3D0;TrueIsMinus1=3D1;Debug=3 D0;CommLog=3D0"=

conn.CursorLocation =3D adUseClient
conn.Open query, "bad", "xxxxxxxx"

query =3D "COPY dunn_main (duns, company, company_short, zip, phone, =
employee_number, legal_id, sic_id, source_id) " & _
"FROM STDIN WITH NULL AS 'NULL' DELIMITER AS ','"
conn.Execute query, , adCmdText + adExecuteNoRecords + adAsyncExecute

In the driver logging I can see that it's waiting for the data now, but =
I can't really figure out how to deliver it. Since the source data (as a =
text file with fixed length fields) is only available on client side and =
needs some processing before being ready to import I'm using something =
like this to prepare the data:=20

    Private Type Dunn_Record
CO_NAME As String * 90
PCODE As String * 8
DUNS As String * 9
EMPS_COMP As String * 9
LE As String * 2
L As String * 1
TEL_NBR As String * 14
US72 As String * 4
crlf As String * 2
End Type
Dim record As Dunn_Record
Dim filehandle As Integer
Dim filename As String
Dim numLines as long
Dim line As Long
filehandle =3D FreeFile
filename =3D "E:\source.txt"
Open filename For Random Access Read Lock Read Write As #filehandle =
Len =3D Len(record)
numLines =3D LOF(1) / Len(record)
For line =3D 2 to numLines
Get #filehandle, line, record
With record
query =3D query & CLng(.DUNS) & ","
query =3D query & "'" & Replace(Trim(.CO_NAME), "'", =
"''") & "',"
query =3D query & "'" & ascii_easy(.CO_NAME) & =
"',"
query =3D query & "'" & Trim(.PCODE) & "',"
query =3D query & phone(.TEL_NBR) & ","
If Len(Trim(.EMPS_COMP)) Then query =3D query & CLng(.EMPS_=
COMP) Else query =3D query & "NULL"
query =3D query & ","
If Len(Trim(.LE)) Then query =3D query & CLng(.LE) Else =
query =3D query & "NULL"
query =3D query & ","
query =3D query & CLng(.US72) & ","
query =3D query & rs!source_id
End With
'DELIVER THE DATA IN query TO THE DRIVER
Next line
I have tried several methods to deliver the prepared data to the =
driver but without any succes.=20



  • Writing to STDOUT
        Private Declare Function GetStdHandle =
    Lib "Kernel32" (ByVal nStdHandle As Long) As Long
    Private Declare Function WriteFile Lib "Kernel32" (ByVal hFile As =
    Long, ByVal lpBuffer As String, ByVal nNumberOfBytesToWrite As Long, =
    lpNumberOfBytesWritten As Long, lpOverlapped As Any) As Long
    Private Const STD_OUTPUT_HANDLE =3D -11&
    Dim stdhandle As Long
    Dim llResult As Long
    stdhandle =3D GetStdHandle(STD_OUTPUT_HANDLE)
    WriteFile stdhandle, query, Len(query), llResult, ByVal 0&

  • Writing to a socket
        Dim socket As New Winsock
    With socket
    .Protocol =3D sckUDPProtocol
    .RemoteHost =3D "10.100.1.24"
    .RemotePort =3D 2345
    .Connect
    End With
    socket.SendData query

  • Executing it
        conn.Execute query

  • Writing to some stream
        Dim str As New Stream
    With str
    .Mode =3D adModeWrite
    .Open
    End With
    str.WriteText query

So basically my question is : how do I deliver the prepared data to the =
driver? Any help (tips, working code, example, ...) would be appreciated. p>=20

Best regards



--=__Part7250D6B8.1__=--

Antw: COPY FROM

am 08.02.2006 17:30:53 von Thomas Holschen

Hi Bart,

Just create an ODBC Entry on your local computer,
add a Refernce to ActiveX Dataobjects 2.8 oder 2.7 to your vbp
Projekt,
open an ADODB.connection to the Server and send SQL-Insert Statements.

Little Example
Private Function Insert()
Dim DBS As New ADODB.Connection
Dim SQLString As String
DBS.Open "Provider=3DMSDASQL.1;Persist Security Info=3DFalse;Extended
Properties=3DDSN=3DYourODBCDatabaseName;"

SQLString =3D "Insert into SomeTable (Field1,Field2,Field3) Values
('111','aaa','bbb')"
DBS.Execute SQLString
End Function

Hope that helps... Your Mail is a little bit "unreadable" ;-)

regards, Thomas.





--=20

_____________________________________________
Hela Gewürzwerk Hermann Laue GmbH & Co.KG
EDV
Thomas Holschen=20
Beimoorweg 11
22926 Ahrensburg

Tel. : +49 4102/496-381
http://www.hela-food.de=20
_____________________________________________

>>> "Bart Degryse" schrieb am Mittwoch, 8.
Februar 2006
um 11:03 in Nachricht :

> Dear,
> I need to do a bulk upload (2,600,000 records) of data into a
PostgreSQL=20
> (v8.0.3) table. I'm trying to achieve this from Visual Basic with ADO
and=20
> psqlODBC (v8.1.2) but I can't get it working. Currently my code looks
like=20
> this. Dim conn As New ADODB.Connection Dim query As String =20
'DSN less=20
> connection query =3D "DRIVER=3D{PostgreSQL=20
>
Unicode};SERVER=3D10.100.1.24;PORT=3D2345;DATABASE=3Dbigdb;B oolsAsChar=3D0;=
TrueIsMin
> us1=3D1;Debug=3D0;CommLog=3D0" conn.CursorLocation =3D adUseClient=20=

conn.Open=20
> query, "bad", "xxxxxxxx" query =3D "COPY dunn_main (duns, company,=20
> company_short, zip, phone, employee_number, legal_id, sic_id,
source_id) " & _=20
> "FROM STDIN WITH NULL AS 'NULL' DELIMITER AS ','" =20
conn.Execute=20
> query, , adCmdText + adExecuteNoRecords + adAsyncExecute
> In the driver logging I can see that it's waiting for the data now,
but I=20
> can't really figure out how to deliver it. Since the source data (as
a text=20
> file with fixed length fields) is only available on client side and
needs=20
> some processing before being ready to import I'm using something like
this to=20
> prepare the data:=20
> Private Type Dunn_Record CO_NAME As String * 90 =20=

PCODE As=20
> String * 8 DUNS As String * 9 EMPS_COMP As String * 9
LE=20
> As String * 2 L As String * 1 TEL_NBR As String * 14 =
=20

> US72 As String * 4 crlf As String * 2 End Type Dim
record As=20
> Dunn_Record Dim filehandle As Integer Dim filename As String =
=20
Dim=20
> numLines as long Dim line As Long filehandle =3D FreeFile =20
filename =
> "E:\source.txt" Open filename For Random Access Read Lock Read
Write As=20
> #filehandle Len =3D Len(record) numLines =3D LOF(1) / Len(record)=20=

For line=20
> =3D 2 to numLines Get #filehandle, line, record With
record =20
> query =3D query & CLng(.DUNS) & "," query =3D query & "'"
&=20
> Replace(Trim(.CO_NAME), "'", "''") & "'," query =3D query &
"'" &=20
> ascii_easy(.CO_NAME) & "'," query =3D query & "'" &
Trim(.PCODE) & "',"
> query =3D query & phone(.TEL_NBR) & "," If=20
> Len(Trim(.EMPS_COMP)) Then query =3D query & CLng(.EMPS_COMP) Else
query =3D query=20
> & "NULL" query =3D query & "," If Len(Trim(.LE))
Then query=20
> =3D query & CLng(.LE) Else query =3D query & "NULL" query =3D
query & "," =20
> query =3D query & CLng(.US72) & "," query =3D query &

> rs!source_id End With 'DELIVER THE DATA IN query TO THE
DRIVER
> Next lineI have tried several methods to deliver the prepared data
to the=20
> driver but without any succes.=20
> Writing to STDOUT
> Private Declare Function GetStdHandle Lib "Kernel32" (ByVal
nStdHandle=20
> As Long) As Long Private Declare Function WriteFile Lib "Kernel32"
(ByVal=20
> hFile As Long, ByVal lpBuffer As St
ring, ByVal nNumberOfBytesToWrite
As Long,=20
> lpNumberOfBytesWritten As Long, lpOverlapped As Any) As Long =20
Private Const=20
> STD_OUTPUT_HANDLE =3D -11& Dim stdhandle As Long Dim llResult As
Long
> stdhandle =3D GetStdHandle(STD_OUTPUT_HANDLE) WriteFile stdhandle,
query,=20
> Len(query), llResult, ByVal 0&Writing to a socket
> Dim socket As New Winsock With socket .Protocol =
> sckUDPProtocol .RemoteHost =3D "10.100.1.24" .RemotePort
=3D 2345 =20
> .Connect End With socket.SendData queryExecuting it
> conn.Execute queryWriting to some stream
> Dim str As New Stream With str .Mode =3D adModeWrite =
=20

> .Open End With str.WriteText query
> So basically my question is : how do I deliver the prepared data to
the=20
> driver? Any help (tips, working code, example, ...) would be
appreciated.=20
> Best regards
Diese E-Mail enthält vertrauliche und/oder rechtlich geschützte Informa=
tionen. Wenn=20
Sie nicht der richtige Adressat sind oder diese E-Mail irrtümlich erhalte=
n haben,=20
informieren Sie bitte den Absender und löschen Sie diese E-Mail. Das uner=
laubte=20
Kopieren sowie die unbefugte Weitergabe dieser E-Mail ist nicht gestattet. =
Aus=20
Rechts- und Sicherheitsgründen ist die in dieser E-Mail gegebene Informat=
ion nicht=20
rechtsverbindlich.

This e-mail contains confidential and/or privileged information. If you are=
not the=20
intended addressee or have received this e-mail in error please notify the =
sender and=20
delete this e-mail. Any unauthorized copying, disclosure or distribution of=
the material=20
in this e-mail is strictly forbidden. Due to legal and security reasons the=
information=20
contained in this e-mail is not legally binding.

---------------------------(end of broadcast)---------------------------
TIP 9: In versions below 8.0, the planner will ignore your desire to
choose an index scan if your joining column's datatypes do not
match

Re: Antw: COPY FROM

am 08.02.2006 17:34:40 von Bart Degryse

This is a MIME message. If you are reading this text, you may want to
consider changing to a mail reader or gateway that understands how to
properly handle MIME multipart messages.

--=__Part6C4EC8B0.1__=
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Hi Thomas,
That's the way I have it working already. With 2,700,000 records it takes =
quite a lot of time though. According to the PostgreSQL manual bulk =
uploads perform better with the COPY FROM statement. If only I could get =
it to work...
Thanks anyway.

>>> "Thomas Holschen" 2006-02-08 17:30 >>>

Hi Bart,

Just create an ODBC Entry on your local computer,
add a Refernce to ActiveX Dataobjects 2.8 oder 2.7 to your vbp
Projekt,
open an ADODB.connection to the Server and send SQL-Insert Statements.

Little Example
Private Function Insert()
Dim DBS As New ADODB.Connection
Dim SQLString As String
DBS.Open "Provider=3DMSDASQL.1;Persist Security Info=3DFalse;Extended
Properties=3DDSN=3DYourODBCDatabaseName;"
=20
SQLString =3D "Insert into SomeTable (Field1,Field2,Field3) Values
('111','aaa','bbb')"
DBS.Execute SQLString
End Function

Hope that helps... Your Mail is a little bit "unreadable" ;-)

regards, Thomas.





--=20

_____________________________________________
Hela Gewürzwerk Hermann Laue GmbH & Co.KG
EDV
Thomas Holschen=20
Beimoorweg 11
22926 Ahrensburg

Tel. : +49 4102/496-381
http://www.hela-food.de=20
_____________________________________________

>>> "Bart Degryse" schrieb am Mittwoch, 8.
Februar 2006
um 11:03 in Nachricht :

> Dear,
> I need to do a bulk upload (2,600,000 records) of data into a
PostgreSQL=20
> (v8.0.3) table. I'm trying to achieve this from Visual Basic with ADO
and=20
> psqlODBC (v8.1.2) but I can't get it working. Currently my code looks
like=20
> this. Dim conn As New ADODB.Connection Dim query As String =20
'DSN less=20
> connection query =3D "DRIVER=3D{PostgreSQL=20
>
Unicode};SERVER=3D10.100.1.24;PORT=3D2345;DATABASE=3Dbigdb;B oolsAsChar=3D0;=
TrueIsMin
> us1=3D1;Debug=3D0;CommLog=3D0" conn.CursorLocation =3D adUseClient =
=20
conn.Open=20
> query, "bad", "xxxxxxxx" query =3D "COPY dunn_main (duns, company,=20
> company_short, zip, phone, employee_number, legal_id, sic_id,
source_id) " & _=20
> "FROM STDIN WITH NULL AS 'NULL' DELIMITER AS ','" =20
conn.Execute=20
> query, , adCmdText + adExecuteNoRecords + adAsyncExecute
> In the driver logging I can see that it's waiting for the data now,
but I=20
> can't really figure out how to deliver it. Since the source data (as
a text=20
> file with fixed length fields) is only available on client side and
needs=20
> some processing before being ready to import I'm using something like
this to=20
> prepare the data:=20
> Private Type Dunn_Record CO_NAME As String * 90 =20
PCODE As=20
> String * 8 DUNS As String * 9 EMPS_COMP As String * 9 =20
LE=20
> As String * 2 L As String * 1 TEL_NBR As String * 14 =20
=20
> US72 As String * 4 crlf As String * 2 End Type Dim
record As=20
> Dunn_Record Dim filehandle As Integer Dim filename As String =20
Dim=20
> numLines as long Dim line As Long filehandle =3D FreeFile =20
filename =
> "E:\source.txt" Open filename For Random Access Read Lock Read
Write As=20
> #filehandle Len =3D Len(record) numLines =3D LOF(1) / Len(record) =
=20
For line=20
> =3D 2 to numLines Get #filehandle, line, record With
record =20
> query =3D query & CLng(.DUNS) & "," query =3D query & =
"'"
&=20
> Replace(Trim(.CO_NAME), "'", "''") & "'," query =3D query &
"'" &=20
> ascii_easy(.CO_NAME) & "'," query =3D query & "'" &
Trim(.PCODE) & "'," =20
> query =3D query & phone(.TEL_NBR) & "," If=20
> Len(Trim(.EMPS_COMP)) Then query =3D query & CLng(.EMPS_COMP) Else
query =3D query=20
> & "NULL" query =3D query & "," If Len(Trim(.LE))
Then query=20
> =3D query & CLng(.LE) Else query =3D query & "NULL" query =3D
query & "," =20
> query =3D query & CLng(.US72) & "," query =3D query =
&

> rs!source_id End With 'DELIVER THE DATA IN query TO THE
DRIVER =20
> Next lineI have tried several methods to deliver the prepared data
to the=20
> driver but without any succes.=20
> Writing to STDOUT
> Private Declare Function GetStdHandle Lib "Kernel32" (ByVal
nStdHandle=20
> As Long) As Long Private Declare Function WriteFile Lib "Kernel32"
(ByVal=20
> hFile As Long, ByVal lpBuffer As St
ring, ByVal nNumberOfBytesToWrite
As Long,=20
> lpNumberOfBytesWritten As Long, lpOverlapped As Any) As Long =20
Private Const=20
> STD_OUTPUT_HANDLE =3D -11& Dim stdhandle As Long Dim llResult As
Long =20
> stdhandle =3D GetStdHandle(STD_OUTPUT_HANDLE) WriteFile stdhandle,
query,=20
> Len(query), llResult, ByVal 0&Writing to a socket
> Dim socket As New Winsock With socket .Protocol =
> sckUDPProtocol .RemoteHost =3D "10.100.1.24" .RemotePort
=3D 2345 =20
> .Connect End With socket.SendData queryExecuting it
> conn.Execute queryWriting to some stream
> Dim str As New Stream With str .Mode =3D adModeWrite =
=20
=20
> .Open End With str.WriteText query
> So basically my question is : how do I deliver the prepared data to
the=20
> driver? Any help (tips, working code, example, ...) would be
appreciated.=20
> Best regards
Diese E-Mail enthält vertrauliche und/oder rechtlich geschützte =
Informationen. Wenn=20
Sie nicht der richtige Adressat sind oder diese E-Mail irrtümlich =
erhalten haben,=20
informieren Sie bitte den Absender und löschen Sie diese E-Mail. Das =
unerlaubte=20
Kopieren sowie die unbefugte Weitergabe dieser E-Mail ist nicht gestattet. =
Aus=20
Rechts- und Sicherheitsgründen ist die in dieser E-Mail gegebene =
Information nicht=20
rechtsverbindlich.

This e-mail contains confidential and/or privileged information. If you =
are not the=20
intended addressee or have received this e-mail in error please notify the =
sender and=20
delete this e-mail. Any unauthorized copying, disclosure or distribution =
of the material=20
in this e-mail is strictly forbidden. Due to legal and security reasons =
the information=20
contained in this e-mail is not legally binding.



--=__Part6C4EC8B0.1__=
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable
Content-Description: HTML


>


Hi Thomas,

That's the way I have it working already. With 2,700,000 records it =
takes quite a lot of time though. According to the PostgreSQL manual bulk =
uploads perform better with the COPY FROM statement. If only I could get =
it to work...

Thanks anyway.

>>> "Thomas Holschen" <Thomas.Holsch=
en@hela-food.de> 2006-02-08 17:30 >>>

Hi Bart,

Just create an ODBC Entry on =
your local computer,
add a Refernce to ActiveX Dataobjects 2.8 oder 2.7 =
to your vbp
Projekt,
open an ADODB.connection to the Server and send =
SQL-Insert Statements.

Little Example
Private Function Insert() R>    Dim DBS As New ADODB.Connection
    =
Dim SQLString As String
    DBS.Open "Provider=3DMSDASQL.=
1;Persist Security Info=3DFalse;Extended
Properties=3DDSN=3DYourODBCData=
baseName;"
   
    SQLString =3D =
"Insert into SomeTable (Field1,Field2,Field3) Values
('111','aaa','bbb')=
"
    DBS.Execute SQLString
End Function

Hope =
that helps... Your Mail is a little bit "unreadable" ;-)

regards, =
Thomas.





--

_________________________________=
____________
Hela Gewürzwerk Hermann Laue GmbH & Co.KG
EDV
T=
homas Holschen
Beimoorweg 11
22926 Ahrensburg

Tel. : +49 =
4102/496-381
http://www.hela-food.de=

_____________________________________________

>>> =
"Bart Degryse" <Bart.Degryse@indicator.be> schrieb am Mittwoch, =
8.
Februar 2006
um 11:03 in Nachricht <s3e9d02f.034@webaccess.indi=
cator.be>:

> Dear,
> I need to do a bulk upload =
(2,600,000 records) of data into a
PostgreSQL
> (v8.0.3) table. =
I'm trying to achieve this from Visual Basic with ADO
and
> =
psqlODBC (v8.1.2) but I can't get it working. Currently my code looks
li=
ke
> this.    Dim conn As New ADODB.Connection &=
nbsp;  Dim query As String  
'DSN less
> =
connection    query =3D "DRIVER=3D{PostgreSQL
>
Un=
icode};SERVER=3D10.100.1.24;PORT=3D2345;DATABASE=3Dbigdb;Boo lsAsChar=3D0;Tr=
ueIsMin
> us1=3D1;Debug=3D0;CommLog=3D0"    conn.Curso=
rLocation =3D adUseClient  
conn.Open
> query, "bad", =
"xxxxxxxx"    query =3D "COPY dunn_main (duns, company, =

> company_short, zip, phone, employee_number, legal_id, sic_id,
s=
ource_id) " & _
>        =
;    "FROM STDIN WITH NULL AS 'NULL' DELIMITER AS ','" =
 
conn.Execute
> query, , adCmdText + adExecuteNoRecords + =
adAsyncExecute
> In the driver logging I can see that it's waiting =
for the data now,
but I
> can't really figure out how to deliver =
it. Since the source data (as
a text
> file with fixed length =
fields) is only available on client side and
needs
> some =
processing before being ready to import I'm using something like
this =
to
> prepare the data:
>     Private =
Type Dunn_Record        CO_NAME As =
String * 90      
PCODE As
> =
String * 8        DUNS As String * =
9        EMPS_COMP As String * 9  =

     LE
> As String * 2   &nb=
sp;    L As String * 1      &n=
bsp; TEL_NBR As String * 14  
   
> =
US72 As String * 4        crlf As =
String * 2    End Type    Dim
record As =

> Dunn_Record    Dim filehandle As Integer  =
;  Dim filename As String  
Dim
> numLines as =
long    Dim line As Long    filehandle =3D =
FreeFile  
filename =3D
> "E:\source.txt"  &=
nbsp; Open filename For Random Access Read Lock Read
Write As
> =
#filehandle Len =3D Len(record)    numLines =3D LOF(1) / =
Len(record)  
For line
> =3D 2 to numLines  =
      Get #filehandle, line, record  &nb=
sp;     With
record     &nb=
sp;
>      query =3D query & CLng(.DUNS=
) & ","          &nbs=
p; query =3D query & "'"
&
> Replace(Trim(.CO_NAME), =
"'", "''") & "',"         =
   query =3D query &
"'" &
> ascii_easy(.CO_NAM=
E) & "',"          &n=
bsp; query =3D query & "'" &
Trim(.PCODE) & "',"  =

>           query =
=3D query & phone(.TEL_NBR) & ","     &nbs=
p;      If
> Len(Trim(.EMPS_COMP)) Then =
query =3D query & CLng(.EMPS_COMP) Else
query =3D query
> =
& "NULL"          &nb=
sp; query =3D query & ","       &nbs=
p;    If Len(Trim(.LE))
Then query
> =3D query =
& CLng(.LE) Else query =3D query & "NULL"    &n=
bsp;       query =3D
query & =
","  
>        &nb=
sp; query =3D query & CLng(.US72) & ","    &nbs=
p;       query =3D query &

> =
rs!source_id        End With  =
      'DELIVER THE DATA IN query TO THE
DRIVER&=
nbsp;
>   Next lineI have tried several methods to =
deliver the prepared data
to the
> driver but without any =
succes.
> Writing to STDOUT
>     Private =
Declare Function GetStdHandle Lib "Kernel32" (ByVal
nStdHandle
> =
As Long) As Long    Private Declare Function WriteFile Lib =
"Kernel32"
(ByVal
> hFile As Long, ByVal lpBuffer As St
ring, =
ByVal nNumberOfBytesToWrite
As Long,
> lpNumberOfBytesWritten As =
Long, lpOverlapped As Any) As Long  
Private Const
> =
STD_OUTPUT_HANDLE =3D -11&    Dim stdhandle As =
Long    Dim llResult As
Long   
> =
stdhandle =3D GetStdHandle(STD_OUTPUT_HANDLE)    WriteFile =
stdhandle,
query,
> Len(query), llResult, ByVal 0&Writing to =
a socket
>     Dim socket As New Winsock &nb=
sp;  With socket        .Protocol =
=3D
> sckUDPProtocol        =
..RemoteHost =3D "10.100.1.24"        =
..RemotePort
=3D 2345  
>      =
..Connect    End With    socket.SendData =
queryExecuting it
>     conn.Execute queryWriting=
to some stream
>     Dim str As New Stream =
   With str        .Mode =3D =
adModeWrite    
 
> .Open  &n=
bsp; End With    str.WriteText query
> So basically =
my question is : how do I deliver the prepared data to
the
> =
driver? Any help (tips, working code, example, ...) would be
appreciated=
..
> Best regards
Diese E-Mail enthält vertrauliche und/oder =
rechtlich geschützte Informationen. Wenn
Sie nicht der richtige =
Adressat sind oder diese E-Mail irrtümlich erhalten haben,
informiere=
n Sie bitte den Absender und löschen Sie diese E-Mail. Das unerlaubte =

Kopieren sowie die unbefugte Weitergabe dieser E-Mail ist nicht =
gestattet. Aus
Rechts- und Sicherheitsgründen ist die in dieser =
E-Mail gegebene Information nicht
rechtsverbindlich.

This =
e-mail contains confidential and/or privileged information. If you are not =
the
intended addressee or have received this e-mail in error please =
notify the sender and
delete this e-mail. Any unauthorized copying, =
disclosure or distribution of the material
in this e-mail is strictly =
forbidden. Due to legal and security reasons the information
contained =
in this e-mail is not legally binding.


--=__Part6C4EC8B0.1__=--

Re: COPY FROM

am 09.02.2006 16:27:08 von Ludek Finstrle

> In the driver logging I can see that it's waiting for the data now,
> but I can't really figure out how to deliver it. Since the source
> data (as a text file with fixed length fields) is only available
> on client side and needs some processing before being ready to import

I think ODBC doesn't support something like standard input ...
Or maybe it does? Do you try print the prepared data to the standard
output?

> So basically my question is : how do I deliver the prepared data
> to the driver? Any help (tips, working code, example, ...)
> would be appreciated.

If you can't find the way you can try to use insert statements.
You may collect multiple insert statements into one transaction
to speed up the data loading.

Regards,

Luf

---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?

http://archives.postgresql.org

Re: COPY FROM

am 17.02.2006 04:29:28 von Kevin Puetz

Ludek Finstrle wrote:

>> In the driver logging I can see that it's waiting for the data now,
>> but I can't really figure out how to deliver it. Since the source
>> data (as a text file with fixed length fields) is only available
>> on client side and needs some processing before being ready to import
>
> I think ODBC doesn't support something like standard input ...
> Or maybe it does? Do you try print the prepared data to the standard
> output?

I don't know about ODBC at the low level, but I've certainly never found a
way to do this with DAO or ADO. I don't *think* it's possible.

>> So basically my question is : how do I deliver the prepared data
>> to the driver? Any help (tips, working code, example, ...)
>> would be appreciated.
>
> If you can't find the way you can try to use insert statements.
> You may collect multiple insert statements into one transaction
> to speed up the data loading.

The fastest approach I've found that *is* VB-friendly is to ship the data
over as a bound parameter to a stored procedure that unpacks it into rows
on the server side (writing a suitable function returning SETOF RECORD to
split apart the string or blob). I don't actually know if there's an upper
limit on the size of such arguments, but I've pushed 30k rows or so (~1MiB
of total data) without difficulty using psqlodbc and ADO.Command objects.
Since that's past 64kiB, and computer programmers not being terribly
creative folk with it comes to max sizes, I suspect this means it'll be
safe up to at least 2GiB if you have the memory to prepare and receive such
a behemoth.

I have a trivial split-on-delimiter char routine for simple stuff, and a
from_csv written in PL/perl using Text::CSV for multi-column data or
anything that needs to potentially quote the delimiter appearing in the
contained data. I'm not actually sure the 'simple' version is even faster
in any meaningful sense, but I wrote it first so it's still around. If
there's interest I should be able to post them, but it's a work project so
I don't have it handy tonight.

For the CSV version, I implemented everything except multi-line values,
which I had no need for - the concept would certainly allow it with a
little more work in the parser function. It streams through the input
splitting consuming lines of input and using return_next to build the
result set, so if the query is able to consume rows as they come out (no
sort or similar) it shouldn't ever need to have both the argument and the
full recordset in memory. But, with my strings only in the megabyte range I
haven't every really tested carefully to prove that it doesn't.

Usage looks roughly like the following

INSERT INTO tbl_foo (foo,bar,baz)
SELECT * FROM from_csv(?) AS t(foo int4, bar text, baz date)

with the arg bound to a string like
'foo,bar,baz
foo1,bar1,baz1
foo2,bar2,baz2'

IIRC, this took the time to load the data from ~45 seconds (using a series
of INSERTs within a single txn) to about 500ms (seemingly pretty much
network constrained), so the difference is pretty dang dramatic.

You have to be careful to stringify non-text values in a way that postgres
is happy with when you pack the argument, and then the type statements in
the AS clause will coerce things so the rest of the query can ignore the
fact they were delivered packed in text. YMMV. One could also use something
other than CSV as the serialization, and the typesafety and
serialization/parsing efficiency might be better if you did, but this was
good enough for me and is nicely generic. Someday I mifhr also do one for
the QDataStream's packing shipped over in a blob, since that would let my
other C++/Qt apps have a more type-strict container, but that hasn't
happened yet.

This technique also allows you to materialize tabular 'immediate' data for a
query in its FROM statement, which can be quite handy. I've actually
replaced quite a few instances where I used to prepare a temp table or loop
repeating a prepared SELECT varying the arguments by doing so. It avoids
the repeated network latency (important in my case, though obviously not if
the DB is local) and lets me feed in all the search data on one shot, so
the db can often switch techniques from a series of hash or index lookups
to something that shows better locality - depending on the structure of the
query it can be an enormous win (one important operation went from 90s to
~300ms).

> Regards,
>
> Luf


---------------------------(end of broadcast)---------------------------
TIP 9: In versions below 8.0, the planner will ignore your desire to
choose an index scan if your joining column's datatypes do not
match